//
/**
 * Filename: sync_parent_child.c
 * Author:   csbonkers
 * Contact:  forever65535@qq.com
 * Date:     2021/6/20
 * Description:
 *    课后习题 10.6
 *       父子进程交替
 */

#include "apue.h"
#include <time.h>

#define FNAME "counter.lock"

static int tick_tock();
const struct timespec INTERVAL = {0,800000000}; // 0.8s

int main(int argc, char *argv[]) {

  TELLWAIT(); //setup sync signal facility
  setbuf(stdout, NULL);

  int fd =open(FNAME, O_RDWR | O_CREAT, FILE_MODE);
  //reset counter to zero
  int reset = 0;
  write(fd,&reset, sizeof(int));

  pid_t pid;
  if((pid = fork()) < 0){
    err_sys("fork error");
  }else if(pid == 0){
    // child
    for(;;){
      WAIT_PARENT(); // parent go first
      printf("child:\ttock(%d)\n", tick_tock(fd));
      nanosleep(&INTERVAL, NULL);
      TELL_PARENT(getppid());
    }
    exit(0);
  }
  // parent

  for(;;){
    printf("parent:\ttick(%d)\n",tick_tock(fd));
    nanosleep(&INTERVAL,NULL); // slowly
    TELL_CHILD(pid);
    WAIT_CHILD();
  }

}

int tick_tock(int fd){
  char b[4] ={0};
  lseek(fd, 0, SEEK_SET);
  int rn = read(fd, b, 4);
  int *pi = (int *)b;
  *pi = rn == 0 ? 0: *pi+ 1;
  lseek(fd, 0, SEEK_SET);
  write(fd, b, 4);
  return *pi;
}